<header>
    3D绘图 WebGL
</header>
<h2>
    引入
</h2>
<pre>
import webglRender from './src/tool/webgl/index';
</pre>
<h2>
    使用
</h2>
<p>
    传递一个canvas结点，返回的是一个对象：
</p>
<pre>
var webgl = webglRender(document.getElementsByTagName('canvas')[0]);
</pre>
<h3>
    属性
</h3>
<h4>
    _gl_
</h4>
<pre>
var gl = webgl._gl_;
</pre>
<p>
    内部维护的WebGL对象实例，你可以通过他来直接调用原生方法。
</p>
<h3>
    着色器
</h3>
<pre>
<!-- 顶点着色器 -->
<script type='x-shader/x-vertex' id='vs'>
    void main(){}
</script>
</pre>
<pre>
<!-- 片段着色器 -->
<script type='x-shader/x-fragment' id='fs'>
    void main(){}
</script>
</pre>
<p>
    在JavaScript层面上着色器就是两段字符串，调用下面的便可以让着色器生效：
</p>
<pre>
webgl.shader(
    document.getElementById('vs').innerHTML,
    document.getElementById('fs').innerHTML
);
</pre>
<h3>
    设置数据
</h3>
<p>
    我们知道varying是只读的，可以是除了数组和结构体外的任意类型，主要用于两个着色器间数据传递，因此，设置数据其实涉及的是attribue和uniform类型的变量（只能是float、vec2、vec3、vec4和mat2、mat3、mat4其中的一种类型）。
</p>
<h4>
    attribue
</h4>
<pre>
webgl.setAttribute[1,2,3,4][f,i](location, v0, v1, v2, v3);
</pre>
<h4>
    uniform
</h4>
<pre>
webgl.setUniform[1,2,3,4][f,i](location, v0, v1, v2, v3);
</pre>
<p>
    此外，如果设置的数据是矩阵：
</p>
<pre>
webgl.setUniformMatrix[2,3,4]fv(location, value);
</pre>
<h3>
    缓冲区
</h3>
<p>
    缓冲区是一种更快速的给GPU大量数据的特殊通道，为了使用缓冲区，首先需要创建一个缓冲区：
</p>
<pre>
var buffer = webgl.buffer(isElement);
</pre>
<p>
    在创建的时候需要传递一个boolean值类型的参数isElement，默认false表示缓冲区中保存了包含顶点的数据，如果传递true表示缓冲区保存了包含顶点的索引值。
</p>
<p>
    缓冲区创建好了以后，你就可以直接往缓冲区里面写入数据了：
</p>
<pre>
buffer.write(data);
</pre>
<p>
    如果你创建的缓冲区是包含顶点的索引值的话，可能到这一步就结束了，否则，你可能还需要把缓冲区中的数据分配给具体的使用者：
</p>
<pre>
buffer.use(location, size, stride, offset);
</pre>
<ol>
    <li>
        location：字符串类型，对应顶点着色器中定义的attribute类型的变量名；
    </li>
    <li>
        size：整数，表示一个完整的数据的个数；
    </li>
    <li>
        stride：整数，表示写入缓冲区数据一组的个数；
    </li>
    <li>
        offset：整数，表示读取起点。
    </li>
</ol>
<h3>
    纹理
</h3>
<p>
    纹理是片元着色器在逐片元过程中使用的，类似贴图，使用的第一步也是创建一个纹理：
</p>
<pre>
var texture = webgl.texture(type[, unit]);
</pre>
<p>
    type表示纹理的类型，unit表示使用哪个纹理单元（开启的编号，可选，默认0）。
</p>
<p>
    因为纹理有很多种，下面列出目前支持的类型：
</p>
<ol>
    <li>
        "2d"：二维纹理(unit只有在这种纹理类型下才需要传递)；
    </li>
    <li>
        "cube"：立方体纹理。
    </li>
</ol>
<p>
    纹理创建好了以后，你需要把材料（比如图片等）和纹理绑定。
</p>
<p>
    如果你使用的是2d纹理，你应该这样绑定（假如我们这里已经准备好了一张图片img）：
</p>
<pre>
texture.useImage(img);
</pre>
<p>
    而如果你使用的是cube纹理，你应该这样绑定（假如我们这里已经准备好了六张图片img1~img6）：
</p>
<pre>
texture.useCube([img1,img2,img3,img4,img5,img6], width, height);
</pre>
<p>
    到这一步，纹理准备工作已经完成了，后面的就是在片元着色器中去使用这个纹理了。
</p>
<h3>
    画笔
</h3>
<pre>
var painter=webgl.painter();
</pre>
<h4>
    绘图方法
</h4>
<table>
    <thead>
        <tr>
            <td>类型</td>
            <td>语句</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>点</td>
            <td>painter.points(first, count[, type]);</td>
        </tr>
        <tr>
            <td>直线</td>
            <td>painter.lines(first, count[, type]);</td>
        </tr>
        <tr>
            <td>连续直线</td>
            <td>painter.stripLines(first, count[, type]);</td>
        </tr>
        <tr>
            <td>闭合直线</td>
            <td>painter.loopLines(first, count[, type]);</td>
        </tr>
        <tr>
            <td>三角形</td>
            <td>painter.triangles(first, count[, type]);</td>
        </tr>
        <tr>
            <td>共边三角形</td>
            <td>painter.stripTriangles(first, count[, type]);</td>
        </tr>
        <tr>
            <td>旋转围绕三角形</td>
            <td>painter.fanTriangles(first, count[, type]);</td>
        </tr>
    </tbody>
</table>
<p class="warn">
    我们注意到每个方法最后都有一个可选参数type，表示索引值类型（"byte"或"short"），如果你希望借助顶点索引来绘制，请传递这个参数。
</p>
<h4>
    辅助方法
</h4>
<p>
    开启深度计算：
</p>
<pre>
painter.openDeep();
</pre>